package com.qd.common.commonwidget;

import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.Scroller;


/**
 * 自定义ViewGroup
 * 左滑删除 item
 */
/*
	1. 如何得到contentView和menuView对象?
		1). 重写onAttachedToWindow()
		2). 调用viewGroup.getChildAt(index)
	2. 如何得到contentView和menuView的宽高?
		1). 重写onMeasure()
		2). 调用getMeasuredWidth()和getMeasuredHeight()
	3. 如何给contentView和menuView进行初始化布局定位?
		1). 重写onLayout()
		2). 调用layout()对contentView与menuView进行布局定位
  	4. 如何拖动contentView与menuView?
		1). 重写onTouchEvent(), 计算移动时的偏移量
		2). 通过scrollTo()来进行同步移动
	5. 如何实现手指离开自动平滑打开/关闭
		1). 在UP时, 根据当前偏移量判断是需要打开还是关闭
		2). 使用Scroller对象的startScroll()实现平滑滚动
	6. 如何解决手指滑动时ListView垂直方向滚动和SwipeView水平滑动的冲突问题?
		1). 在move事件时, 获取x轴和y轴方向的移动距离dx, dy
		2). 如果distanceX>distanceY, 执行requestDisallowInterceptTouchEvent(true), 使ListView不能拦截event
	7. 如何解决SwipeView滑动与ContentView/menuView点击事件的冲突问题?
		1). 重写onInterceptTouchEvent()
		2). 根据x轴方向的总偏移量是否大于5来决定是否拦截事件
	8. 如何让ListView中同时只有一个SwipeView被打开?
		1). 在SwipeView中, 定义监听接口,在接口中定义回调方法
		2). 在SwipeView中, 定义设置监听接口对象的方法
		3). 在SwipeView中, 在事件发生时, 调用监听对象处理
		4). 在Activity的Adapter中, 为每个SwipeView对象设置监听器对象, 在回调方法中做处理       
 */

/*
 * 1. 只能打开一个
 * 2. 如果按下的item不是打开的item, 就关闭打开的item
 */
public class SwipeLayout extends FrameLayout {

    private View contentView, menuView;
    private int contentWidth, menuWidth, viewHeight;
    private Scroller scroller;

    public SwipeLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        scroller = new Scroller(context);
    }

    @Override
    protected void onFinishInflate() {//加载布局完成, 所有子View对象都创建好后调用
        super.onFinishInflate();
        contentView = getChildAt(0);
        menuView = getChildAt(1);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        contentWidth = contentView.getMeasuredWidth();
        menuWidth = menuView.getMeasuredWidth();
        viewHeight = contentView.getMeasuredHeight();
    }

    //对menuView进行
    @Override
    protected void onLayout(boolean changed, int left, int top, int right,
                            int bottom) {
        super.onLayout(changed, left, top, right, bottom);
        menuView.layout(contentWidth, 0, contentWidth + menuWidth, viewHeight);
    }

    private int lastX, lastY, downX, downY;

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        int eventX = (int) event.getRawX();
        int eventY = (int) event.getRawY();
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                lastX = eventX;

                break;
            case MotionEvent.ACTION_MOVE:
                int dx = eventX - lastX;
                //移动view
                int toScrollX = getScrollX() - dx;
                //toScrollX范围[0,menuWidth]
                if (toScrollX < 0) {
                    toScrollX = 0;
                } else if (toScrollX > menuWidth) {
                    toScrollX = menuWidth;
                }
                scrollTo(toScrollX, getScrollY());

                //比较totalDx与totalDy的大小, 如果totalDx>totalDy反拦截
                int totalDx = Math.abs(eventX - downX);
                int totalDy = Math.abs(eventY - downY);
                //不需要判断totalDx>5
                if (totalDx > totalDy) {//反拦截
                    getParent().requestDisallowInterceptTouchEvent(true);
                }

                //更新lastX
                lastX = eventX;
                break;
            case MotionEvent.ACTION_UP:
                int scrollX = getScrollX();
                if (scrollX > menuWidth / 2) {
                    open();//打开
                } else {
                    close();//关闭
                }
                break;

            default:
                break;
        }
        return true;
    }

    /**
     * 平滑关闭
     */
    public void close() {
        //通知监听器
        if (onSwipeChangeListener != null) {
            onSwipeChangeListener.onClose(this);
        }
        scroller.startScroll(getScrollX(), getScrollY(), -getScrollX(), 0);
        invalidate();
    }

    /**
     * 平滑打开
     */
    public void open() {
        //通知监听器
        if (onSwipeChangeListener != null) {
            onSwipeChangeListener.onOpen(this);
        }

        scroller.startScroll(getScrollX(), getScrollY(), menuWidth - getScrollX(), 0);
        invalidate();
    }

    @Override
    public void computeScroll() {
        if (scroller.computeScrollOffset()) {
            scrollTo(scroller.getCurrX(), scroller.getCurrY());
            invalidate();
        }
    }

    /**
     * 判断是否是打开的状态
     *
     * @return
     */
    public boolean isOpen() {
        return getScrollX() == menuWidth;
    }

    //拦截事件
    @Override
    public boolean onInterceptTouchEvent(MotionEvent event) {
        boolean intercept = false;//默认不拦截了
        //计算总的移动距离, 如果大于了5, 才拦截
        int eventX = (int) event.getRawX();
        int eventY = (int) event.getRawY();
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                downX = lastX = eventX;
                downY = lastY = eventY;

                //通知监听器
                if (onSwipeChangeListener != null) {
                    onSwipeChangeListener.onDown(this);
                }

                break;
            case MotionEvent.ACTION_MOVE:
                int totalDx = Math.abs(eventX - downX);
                if (totalDx > 10) {
                    intercept = true;
                }
                //更新lastX
                lastX = eventX;
                break;

            default:
                break;
        }
        return intercept;//返回true就代表拦截
    }

    private OnSwipeChangeListener onSwipeChangeListener;

    public void setOnSwipeChangeListener(OnSwipeChangeListener onSwipeChangeListener) {
        this.onSwipeChangeListener = onSwipeChangeListener;
    }

    public interface OnSwipeChangeListener {
        public void onOpen(SwipeLayout swipeLayout);//当swipLayout打开时调用

        public void onClose(SwipeLayout swipeLayout);//当swipLayout关闭时调用

        public void onDown(SwipeLayout swipeLayout);//当按下swipLayout时调用
    }
}
